package com.vk.project.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vk.project.common.DeleteRequest;
import com.vk.project.common.ErrorCode;
import com.vk.project.common.IdRequest;
import com.vk.project.exception.BusinessException;
import com.vk.project.mapper.InterfaceInfoMapper;
import com.vk.project.mapper.UserInterfaceInfoMapper;
import com.vk.project.model.dto.interfaceinfo.InterfaceInfoInvokeRequest;
import com.vk.project.model.dto.interfaceinfo.InterfaceInfoQueryRequest;
import com.vk.project.model.enums.InterfaceInfoStatusEnum;
import com.vk.project.model.vo.InterfaceInfoVO;
import com.vk.project.model.vo.UserVO;
import com.vk.project.service.UserInterfaceInfoService;
import com.vk.project.service.UserService;
import com.vk.project.untils.Const;
import com.vk.vkapiclientsdk.client.VkApiClient;
import com.vk.vkapicommon.model.entity.InterfaceInfo;
import com.vk.project.service.InterfaceInfoService;
import com.vk.vkapicommon.model.entity.User;
import com.vk.vkapicommon.model.entity.UserInterfaceInfo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * @ClassName : InterfaceInfoServiceImpl
 * @Description : 接口信息操作实现类
 * @Author : LYQ
 * @Date: 2023-11-23 22:07:58
 */
@Service
public class InterfaceInfoServiceImpl extends ServiceImpl<InterfaceInfoMapper, InterfaceInfo>
        implements InterfaceInfoService {

    @Autowired
    private UserService userService;

    @Autowired
    private InterfaceInfoMapper interfaceInfoMapper;

    @Autowired
    private UserInterfaceInfoMapper userInterfaceInfoMapper;

    @Autowired
    private UserInterfaceInfoService userInterfaceInfoService;

    /**
     * 删除接口信息
     *
     * @param deleteRequest 删除请求对象
     * @param request       请求体
     * @return
     */
    @Override
    public Boolean deleteInterfaceInfo(DeleteRequest deleteRequest, HttpServletRequest request) {
        // 参数错误
        if (deleteRequest == null || deleteRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        // 获取登录用户
        User user = userService.getLoginUser(request);
        long id = deleteRequest.getId();
        // 判断是否存在
        InterfaceInfo oldInterfaceInfo = this.getById(id);
        // 未找到接口信息
        if (oldInterfaceInfo == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }
        // 仅本人或管理员可删除
        if (!oldInterfaceInfo.getUserId().equals(user.getId()) && !userService.isAdmin(request)) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        }
        // 删除接口信息
        boolean isDeletedInterfaceInfo = this.removeById(id);
        // 删除所有开通该接口的用户记录
        boolean isDeletedUserInterfaceInfo = userInterfaceInfoService.deleteInterfaceInfoByInterfacId(id);

        return isDeletedInterfaceInfo && isDeletedUserInterfaceInfo;
    }

    /**
     * 校验接口
     *
     * @param interfaceInfo 接口信息对象
     * @param add           是否为创建校验
     */
    @Override
    public void validInterfaceInfo(InterfaceInfo interfaceInfo, boolean add) {
        // 如果接口信息为空则抛出异常
        if (interfaceInfo == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        // 获取接口名称
        String name = interfaceInfo.getName();
        // 创建时，所有参数必须非空
        if (add) {
            if (StringUtils.isAnyBlank(name)) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR);
            }
        }
        if (StringUtils.isNotBlank(name) && name.length() > 50) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "名称过长");
        }
    }

    /**
     * 下线接口
     *
     * @param idRequest 接口ID
     * @param request   请求体
     * @return 返回执行结果
     */
    @Override
    public boolean offLineInterface(IdRequest idRequest, HttpServletRequest request) {
        // 如果id为null 或者id小于等于0
        if (idRequest == null || idRequest.getId() <= 0) {
            // 抛出业务异常，表示请求参数错误
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        // 获取idRequest对象id的值
        Long id = idRequest.getId();
        // 判断是否存在
        InterfaceInfo oldInterfaceInfo = this.getById(id);
        // 如果查询到的接口为空
        if (oldInterfaceInfo == null) {
            // 抛出业务异常，表示未找到数据
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }

        // 仅本人或管理员可修改
        InterfaceInfo interfaceInfo = new InterfaceInfo();
        interfaceInfo.setId(id);
        // 将接口的状态设置为 0 下线
        interfaceInfo.setStatus(InterfaceInfoStatusEnum.OFFLINE.getValue());

        // 更新数据库的状态
        boolean result = this.updateById(interfaceInfo);
        // 查询对应的用户接口关系
        List<UserInterfaceInfo> userInterfaceInfoListById = userInterfaceInfoService.getUserInterfaceInfoListById(id);
        // 更新关联用户接口关系状态
        for (UserInterfaceInfo userInterfaceInfo : userInterfaceInfoListById) {
            userInterfaceInfo.setStatus(InterfaceInfoStatusEnum.OFFLINE.getValue());
            LambdaQueryWrapper<UserInterfaceInfo> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(UserInterfaceInfo::getId, userInterfaceInfo.getId());
            userInterfaceInfoMapper.update(userInterfaceInfo,queryWrapper);
        }
        return true;
    }

    /**
     * 上线接口
     *
     * @param interfaceInfoInvokeRequest 要上线的接口对象
     * @param request                    请求体
     * @return 返回执行结果
     */
    @Override
    public boolean onLineInterface(InterfaceInfoInvokeRequest interfaceInfoInvokeRequest, HttpServletRequest request) {
        // 如果id为null 或者id小于等于0
        if (interfaceInfoInvokeRequest == null || interfaceInfoInvokeRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        // 获取接口的Id值
        Long id = interfaceInfoInvokeRequest.getId();
        // 判断是否存在
        InterfaceInfo oldInterfaceInfo = this.getById(id);
        // 如果查询到的接口为空
        if (oldInterfaceInfo == null) {
            // 抛出业务异常，表示未找到数据
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }
        // 设置请求参数
        interfaceInfoInvokeRequest.setUserRequestParams(oldInterfaceInfo.getRequestParams());
        // 如果下面这一步没抛异常，那么就可以成功上线接口，不需要返回值了
        // this.getInvokeResult(interfaceInfoInvokeRequest, request,oldInterfaceInfo);

        InterfaceInfo interfaceInfo = new InterfaceInfo();
        interfaceInfo.setId(id);
        // 将接口的状态设置为 1 开启
        interfaceInfo.setStatus(InterfaceInfoStatusEnum.ONLINE.getValue());

        // 更新数据库的状态
        boolean result = this.updateById(interfaceInfo);
        // 查询对应的用户接口关系
        List<UserInterfaceInfo> userInterfaceInfoListById = userInterfaceInfoService.getUserInterfaceInfoListById(id);
        // 更新关联用户接口关系状态
        for (UserInterfaceInfo userInterfaceInfo : userInterfaceInfoListById) {
            userInterfaceInfo.setStatus(InterfaceInfoStatusEnum.ONLINE.getValue());
            LambdaQueryWrapper<UserInterfaceInfo> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(UserInterfaceInfo::getId, userInterfaceInfo.getId());
            userInterfaceInfoMapper.update(userInterfaceInfo,queryWrapper);
        }

        return true;
    }

    /**
     * 条件查询接口信息
     *
     * @param interfaceInfoQueryRequest 查询条件
     * @param request                   请求体
     * @return 返回接口信息列表
     */
    @Override
    public Page<InterfaceInfoVO> listInterfaceInfoByPage(InterfaceInfoQueryRequest interfaceInfoQueryRequest, HttpServletRequest request) {

        // 当前页数
        long current = interfaceInfoQueryRequest.getCurrent();
        // 每页显示的数量
        long size = interfaceInfoQueryRequest.getPageSize();

        Page<InterfaceInfo> page = new Page<>(current, size);
        IPage<InterfaceInfoVO> pageResult = interfaceInfoMapper.findByCondition(page, interfaceInfoQueryRequest);

        Page<InterfaceInfoVO> interfaceInfoVOPage = new PageDTO<>(page.getCurrent(), page.getSize(), page.getTotal());
        // 将UserVO列表放入分页信息中
        interfaceInfoVOPage.setRecords(pageResult.getRecords());
        return interfaceInfoVOPage;
    }

    /**
     * 接口调用
     *
     * @param interfaceInfoInvokeRequest 接口调用请求体
     * @param request 请求体
     * @param oldInterfaceInfo           接口对象信息
     * @return 返回调用结果
     */
    @Override
    public String getInvokeResult(InterfaceInfoInvokeRequest interfaceInfoInvokeRequest, HttpServletRequest request,InterfaceInfo oldInterfaceInfo) {

        // 获取旧接口的Id
        Long id = oldInterfaceInfo.getId();
        // 获取旧接口请求地址
        String url = oldInterfaceInfo.getUrl();
        // 获取旧接口请求方法类别
        String method = oldInterfaceInfo.getMethod();
        // 获取旧接口请求路径
        String path = oldInterfaceInfo.getPath();
        // 获取旧接口请求参数
        String requestParams = interfaceInfoInvokeRequest.getUserRequestParams();

        //获取SDK客户端
        VkApiClient apiClient = userService.getApiClient(request);

        String invokeResult = null;
        try {
            // 执行方法，调用接口
            invokeResult = apiClient.invokeInterface(id, requestParams, url, method, path);
        } catch (Exception e) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "接口调用失败");
        }
        if (StrUtil.isBlank(invokeResult)) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "接口返回值为空");
        } else {
            JSONObject jsonObject;
            /*try {
                // 将响应结果转换为JSON对象
                jsonObject = JSONUtil.parseObj(invokeResult);
            } catch (Exception e) {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "接口响应参数不规范");//JSON转化失败，响应数据不是JSON格式
            }*/
            // 返回转换后的响应结果
            return invokeResult;
        }
    }
}




